#include "Aux_cmd_define.h"
#include "Aux_yate_hal.h"


//=====================================================================================================================
//=====================================================================================================================
//=====================================================================================================================
//=====================================================================================================================

using namespace TelEngine;

// 注意: 插件名称和动态库名称需要保持一致，否则会导致部分插件管理功能缺失

#define MY_PLUGIN_NAME "mydemo"

namespace {	 // 使用匿名空间


	//===============================
	// 类定义

	class MyPlugin : public Plugin
	{
	public:


		MyPlugin() : Plugin(MY_PLUGIN_NAME)
			, _debug_hdl(0), m_initialized(false)
		{

		}


		~MyPlugin() {

		}

		// 模块初始化函数，会被多次调用
		void initialize(void) override;

		// 引擎启动处理
		void onEngineStart();

		// 引擎退出处理
		void onEngineStop();

		// debug消息
		bool onYateDebug(Message& msg);

		// 消息处理函数
		bool onYateMessage(Message& msg);

		void showLog();

		void demoAny();


	private:

		// 插件对象初始化标记
		bool m_initialized;

		YateMsgHandler* _debug_hdl;


	};

	//===============================
	// 变量定义


	// 实现模块对象
	INIT_PLUGIN(MyPlugin);

	// 配置文件
	static Configuration s_cfg;


	//===============================
	// 功能实现

	void MyPlugin::initialize()
	{
		Output("Initializing module " MY_PLUGIN_NAME);


		// 配置文件，配置文件名可任意指定，
		s_cfg = Engine::configFile(MY_PLUGIN_NAME);
		s_cfg.load();

		int level = s_cfg.getIntValue("debug", "level", TelEngine::debugLevel());
		withDebugEnabler()->debugLevel(level);

		if (!m_initialized) {

			// 设置初始化标记，避免多次调用情况下出现问题
			m_initialized = true;

			// 订阅消息处理
			YateMsgHandler* handler;

			// 引擎启动消息
			handler = new YateMsgHandler(MSG_ENGINE_START);
			handler->_handler = [this](Message& msg) {
				this->onEngineStart();
				return false;
				};
			Engine::install(handler);

			// 引擎退出消息
			handler = new YateMsgHandler(MSG_ENGINE_STOP);
			handler->_handler = [this](Message& msg) {
				this->onEngineStop();
				return false;
				};
			Engine::install(handler);

			int priority = s_cfg.getIntValue("general", "priority", 100);
			handler = new YateMsgHandler(MSG_YATE, priority);
			handler->_handler = [this](Message& msg) {
				return this->onYateMessage(msg);
				};
			Engine::install(handler);

		}

		// 调试消息处理
		int on = s_cfg.getBoolValue("debug", "on", false);
		if (on) {
			if (!_debug_hdl) {
				int priority = s_cfg.getIntValue("debug", "priority", 100);
				_debug_hdl = new YateMsgHandler("Yateshop.debug", priority);
				_debug_hdl->_handler = [this](Message& msg) {
					return this->onYateDebug(msg);
					};
				Engine::install(_debug_hdl);
			}
		}
		else {
			if (_debug_hdl) {
				Engine::uninstall(_debug_hdl);
				delete _debug_hdl;
				_debug_hdl = nullptr;
			}
		}

	}


	void MyPlugin::onEngineStart()
	{


		//Y_WARN("onEngineStart, ***************************");

		//const String& shared = Engine::sharedPath();

		// 用户信息配置路径， 与操作系统的登录用户关联
		//const String& user = Engine::configPath(true);

		// Yate全局配置路径， 与yate的安装路径相关
		//const String& config = Engine::configPath(false);

	}

	void MyPlugin::onEngineStop()
	{

		S_INFO("onEngineStop ");

	}


	bool MyPlugin::onYateMessage(Message& msg)
	{
		String Op = msg.getParam("Op");

		if (Op == "mydemo.show.log") {
			showLog();
			return true;
		}

		return false;
	}

	bool MyPlugin::onYateDebug(Message& msg)
	{

		return false;
	}

	void MyPlugin::showLog()
	{

		LOG_S_TRACE("onEngineStart, *****" << "ssss");
		LOG_S_DEBUG("onEngineStart, *****" << "ssss");
		LOG_S_INFO("onEngineStart, *****" << "ssss");
		LOG_S_ERROR("onEngineStart, *****" << "ssss");
		LOG_S_WARN("onEngineStart, *****" << "ssss");
		LOG_S_FATAL("onEngineStart, *****" << "ssss");

		LOG_SP_TRACE("Hello, %s", "world");
		LOG_SP_DEBUG("Hello, %s", "world");
		LOG_SP_INFO("Hello, %s", "world");
		LOG_SP_ERROR("Hello, %s", "world");
		LOG_SP_WARN("Hello, %s", "world");
		LOG_SP_FATAL("Hello, %s", "world");

		LOG_SF_TRACE("Hello, {}", "world");
		LOG_SF_DEBUG("Hello, {}", "world");
		LOG_SF_INFO("Hello, {}", "world");
		LOG_SF_ERROR("Hello, {}", "world");
		LOG_SF_WARN("Hello, {}", "world");
		LOG_SF_FATAL("Hello, {}", "world");


		LOG_S_TRACE_IF(true, "onEngineStart, *****" << "ssss");
		LOG_S_DEBUG_IF(true, "onEngineStart, *****" << "ssss");
		LOG_S_INFO_IF(true, "onEngineStart, *****" << "ssss");
		LOG_S_ERROR_IF(true, "onEngineStart, *****" << "ssss");
		LOG_S_WARN_IF(true, "onEngineStart, *****" << "ssss");
		LOG_S_FATAL_IF(true, "onEngineStart, *****" << "ssss");

		LOG_SP_TRACE_IF(true, "Hello, %s", "world");
		LOG_SP_DEBUG_IF(true, "Hello, %s", "world");
		LOG_SP_INFO_IF(true, "Hello, %s", "world");
		LOG_SP_ERROR_IF(true, "Hello, %s", "world");
		LOG_SP_WARN_IF(true, "Hello, %s", "world");
		LOG_SP_FATAL_IF(true, "Hello, %s", "world");

		LOG_SF_TRACE_IF(true, "Hello, {}", "world");
		LOG_SF_DEBUG_IF(true, "Hello, {}", "world");
		LOG_SF_INFO_IF(true, "Hello, {}", "world");
		LOG_SF_ERROR_IF(true, "Hello, {}", "world");
		LOG_SF_WARN_IF(true, "Hello, {}", "world");
		LOG_SF_FATAL_IF(true, "Hello, {}", "world");


		LOG_Y_TRACE("onEngineStart, *****" << "ssss");
		LOG_Y_DEBUG("onEngineStart, *****" << "ssss");
		LOG_Y_INFO("onEngineStart, *****" << "ssss");
		LOG_Y_ERROR("onEngineStart, *****" << "ssss");
		LOG_Y_WARN("onEngineStart, *****" << "ssss");
		LOG_Y_FATAL("onEngineStart, *****" << "ssss");


		LOG_YP_TRACE("Hello, %s", "world");
		LOG_YP_DEBUG("Hello, %s", "world");
		LOG_YP_INFO("Hello, %s", "world");
		LOG_YP_ERROR("Hello, %s", "world");
		LOG_YP_WARN("Hello, %s", "world");
		LOG_YP_FATAL("Hello, %s", "world");

		LOG_YF_TRACE("Hello, {}", "world");
		LOG_YF_DEBUG("Hello, {}", "world");
		LOG_YF_INFO("Hello, {}", "world");
		LOG_YF_ERROR("Hello, {}", "world");
		LOG_YF_WARN("Hello, {}", "world");
		LOG_YF_FATAL("Hello, {}", "world");


		LOG_Y_TRACE_IF(true, "onEngineStart, *****" << "ssss");
		LOG_Y_DEBUG_IF(true, "onEngineStart, *****" << "ssss");
		LOG_Y_INFO_IF(true, "onEngineStart, *****" << "ssss");
		LOG_Y_ERROR_IF(true, "onEngineStart, *****" << "ssss");
		LOG_Y_WARN_IF(true, "onEngineStart, *****" << "ssss");
		LOG_Y_FATAL_IF(true, "onEngineStart, *****" << "ssss");


		LOG_YP_TRACE_IF(true, "Hello, %s", "world");
		LOG_YP_DEBUG_IF(true, "Hello, %s", "world");
		LOG_YP_INFO_IF(true, "Hello, %s", "world");
		LOG_YP_ERROR_IF(true, "Hello, %s", "world");
		LOG_YP_WARN_IF(true, "Hello, %s", "world");
		LOG_YP_FATAL_IF(true, "Hello, %s", "world");

		LOG_YF_TRACE_IF(true, "Hello, {}", "world");
		LOG_YF_DEBUG_IF(true, "Hello, {}", "world");
		LOG_YF_INFO_IF(true, "Hello, {}", "world");
		LOG_YF_ERROR_IF(true, "Hello, {}", "world");
		LOG_YF_WARN_IF(true, "Hello, {}", "world");
		LOG_YF_FATAL_IF(true, "Hello, {}", "world");

		LOG_X_ERROR(1, "hello, " << "world");
		LOG_XP_FATAL(1, "Hello, %s", "world");
		LOG_XF_FATAL(1, "Hello, {}", "world");

	}

	void MyPlugin::demoAny()
	{

		DataBlock* buf(new DataBlock());
		Any any(buf);
		DataBlock* b = any_cast<DataBlock*>(any);

		auto bp = any.Get<DataBlock>();

		delete buf;

		//    assert(buf == b);
		//    delete buf;

		

	}

}

/*
* 支持模块内日志宏
*/

TelEngine::DebugEnabler* withDebugEnabler()
{
	return &__plugin;
}

TE::Configuration* get_configuration()
{
	return &s_cfg;
}

const char* get_app_name()
{
	return s_cfg.getValue("general", "app.name", __plugin.name());
}


unsigned long long withDebugSelector = 1;
